package response

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

// 数据返回通用JSON数据结构
type JsonRes struct {
	Code int         `json:"code"` // 错误码((0:成功, 1:失败, >1:错误码))
	Msg  string      `json:"msg"`  // 提示信息
	Data interface{} `json:"data"` // 返回数据(业务接口定义具体数据结构)
}

var (
	CodeNil           = JsonRes{-1, "", nil}                // No error code specified
	CodeOK            = JsonRes{0, "OK", nil}               // It is OK
	CodeParamError    = JsonRes{1, "参数错误", nil}             // Param Error
	CodeMaint         = JsonRes{1, "系统维护中", nil}            // System Maint
	CodeInnerError    = JsonRes{500, "未知错误", nil}           // Internal Error
	CodeNotLogin      = JsonRes{-5, "未登录，请先登录", nil}        // Not Login
	CodeNotAuthorized = JsonRes{401, "Not Authorized", nil} // Not Authorized
)

// 返回标准JSON数据。
func Json(r *ghttp.Request, code int, Msg string, data ...interface{}) {
	var responseData interface{}
	if len(data) > 0 {
		responseData = data[0]
	} else {
		responseData = g.Map{}
	}
	r.Response.WriteJsonExit(JsonRes{
		Code: code,
		Msg:  Msg,
		Data: responseData,
	})
}

func SetHeader(r *ghttp.Request, key string, value string) {
	r.Response.Header().Set(key, value)
}

// 返回标准JSON数据并退出当前HTTP执行函数。
func JsonExit(r *ghttp.Request, code int, Msg string, data interface{}) {
	Json(r, code, Msg, data)
	r.Exit()
}

func SuccessReturn(r *ghttp.Request, Msg string, data interface{}) {
	JsonExit(r, CodeOK.Code, Msg, data)
}

func ErrorReturn(r *ghttp.Request, code int, Msg string) {
	JsonExit(r, code, Msg, nil)
}

func ParamErrorReturn(r *ghttp.Request, Err error) {
	JsonExit(r, CodeParamError.Code, Err.Error(), nil)
}

func NotLoginReturn(r *ghttp.Request) {
	JsonExit(r, CodeNotLogin.Code, CodeNotLogin.Msg, nil)
}

func MaintReturn(r *ghttp.Request) {
	JsonExit(r, CodeMaint.Code, CodeMaint.Msg, nil)
}

func InnerErrorReturn(r *ghttp.Request, Err error) {
	JsonExit(r, CodeInnerError.Code, Err.Error(), nil)
}

// 返回httpcode
func HttpStatusExit(r *ghttp.Request, code int) {
	r.Response.WriteStatusExit(code)
}
